/*
 * Copyright 2010, 2011, 2012 mapsforge.org
 *
 * This program is free software: you can redistribute it and/or modify it under the
 * terms of the GNU Lesser General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License along with
 * this program. If not, see <http://www.gnu.org/licenses/>.
 */
package com.plako.mapper.offline;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.jibble.simpleftp.SimpleFTP;
import org.mapsforge.android.maps.MapActivity;
import org.mapsforge.android.maps.MapView;
import org.mapsforge.android.maps.overlay.ArrayItemizedOverlay;
import org.mapsforge.android.maps.overlay.ArrayWayOverlay;
import org.mapsforge.android.maps.overlay.ItemizedOverlay;
import org.mapsforge.android.maps.overlay.OverlayItem;
import org.mapsforge.android.maps.overlay.OverlayWay;
import org.mapsforge.core.GeoPoint;
import org.mapsforge.map.reader.header.FileOpenResult;

import android.annotation.TargetApi;
import android.app.ActionBar;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.OrientationEventListener;
import android.view.View;
import android.widget.PopupMenu;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.RadioGroup.OnCheckedChangeListener;
import android.widget.Toast;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.plako.mapper.MainActivity;
import com.plako.mapper.NewPointDialogActivity;
import com.plako.mapper.R;
import com.plako.mapper.data.AlertPoint;
import com.plako.mapper.util.PointsExtractor;

/**
 * An application which demonstrates how to use overlays.
 */
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
public class OverlayMapViewer extends MapActivity {
	private static final String JSON_DIR = Environment.getExternalStorageDirectory().getPath() + "/odonym/json/";
	private MapView mapView;
	private ArrayItemizedOverlay itemizedOverlay;
	private static boolean isFirstCreate = true;
	private Ways wayOverlay;
	static Paint wayDefaultPaintFill = new Paint(Paint.ANTI_ALIAS_FLAG);
	static Paint wayDefaultPaintOutline = new Paint(Paint.ANTI_ALIAS_FLAG);

	static {
		wayDefaultPaintFill = new Paint(Paint.ANTI_ALIAS_FLAG);
		wayDefaultPaintFill.setStyle(Paint.Style.STROKE);
		wayDefaultPaintFill.setColor(Color.BLUE);
		wayDefaultPaintFill.setAlpha(160);
		wayDefaultPaintFill.setStrokeWidth(7);
		wayDefaultPaintFill.setStrokeJoin(Paint.Join.ROUND);
		wayDefaultPaintFill.setPathEffect(new DashPathEffect(new float[] { 20, 20 }, 0));

		wayDefaultPaintOutline = new Paint(Paint.ANTI_ALIAS_FLAG);
		wayDefaultPaintOutline.setStyle(Paint.Style.STROKE);
		wayDefaultPaintOutline.setColor(Color.BLUE);
		wayDefaultPaintOutline.setAlpha(128);
		wayDefaultPaintOutline.setStrokeWidth(7);
		wayDefaultPaintOutline.setStrokeJoin(Paint.Join.ROUND);

	}

	private static class MyItemizedOverlay extends ArrayItemizedOverlay {
		private final Context context;

		/**
		 * Constructs a new MyItemizedOverlay.
		 * 
		 * @param defaultMarker
		 *            the default marker (may be null).
		 * @param context
		 *            the reference to the application context.
		 */
		MyItemizedOverlay(Drawable defaultMarker, Context context) {
			super(defaultMarker);
			this.context = context;
		}

		/**
		 * Handles a tap event on the given item.
		 */
		@Override
		protected boolean onTap(int index) {
			OverlayItem item = createItem(index);
			if (item != null) {
				Builder builder = new AlertDialog.Builder(this.context);
				builder.setIcon(android.R.drawable.ic_menu_info_details);
				builder.setTitle(item.getTitle());
				builder.setMessage(item.getSnippet());
				builder.setPositiveButton("OK", null);
				builder.show();
			}
			return true;
		}
	}

	Drawable itemDefaultMarker;
	Drawable rasMarker;

	Drawable masquedMarker;

	Drawable illisibleMarker;

	Drawable manqMarker;

	Drawable malMarker;
	private RadioGroup filterRadio;
	private RadioButton checked;
	public static List<AlertPoint> alertPoints;
	public static List<OverlayItem> alertItems;
	static {
		alertPoints = new ArrayList<AlertPoint>();
		alertItems = new ArrayList<OverlayItem>();
	}
	private static final File MAP_FILE = new File(Environment.getExternalStorageDirectory().getPath(),
			"/odonym/settings/mission.map");
	private static final File GEO_JSON_FILE = new File(Environment.getExternalStorageDirectory().getPath(),
			"/odonym/settings/features.geoJson");
	private AlertPointDialog dialog;
	private String login;

	// private static Polygon createPolygon(List<GeoPoint> geoPoints) {
	// PolygonalChain polygonalChain = new PolygonalChain(geoPoints);
	//
	// Paint paintFill = new Paint(Paint.ANTI_ALIAS_FLAG);
	// paintFill.setStyle(Paint.Style.FILL);
	// paintFill.setColor(Color.YELLOW);
	// paintFill.setAlpha(96);
	// paintFill.setStrokeCap(Cap.ROUND);
	// paintFill.setStrokeJoin(Paint.Join.ROUND);
	//
	// Paint paintStroke = new Paint(Paint.ANTI_ALIAS_FLAG);
	// paintStroke.setStyle(Paint.Style.STROKE);
	// paintStroke.setColor(Color.GRAY);
	// paintStroke.setAlpha(192);
	// paintStroke.setStrokeWidth(5);
	// paintStroke.setStrokeCap(Cap.ROUND);
	// paintStroke.setStrokeJoin(Paint.Join.ROUND);
	//
	// return new Polygon(Arrays.asList(polygonalChain), paintFill, paintStroke);
	// }

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		ActionBar actionBar = getActionBar();
		actionBar.setBackgroundDrawable(new ColorDrawable(Color.parseColor("#330000ff")));
		actionBar.setHomeButtonEnabled(true);
		OrientationEventListener orientationListener = new OrientationEventListener(this) {

			@Override
			public void onOrientationChanged(int orientation) {
				if (orientation == 90 || orientation == 270)
					findViewById(R.id.filter).setVisibility(View.VISIBLE);
				else if (orientation == 0 || orientation == 180)
					findViewById(R.id.filter).setVisibility(View.INVISIBLE);

			}
		};

		orientationListener.enable();

		setContentView(R.layout.activity_main_activity);
		// LinearLayout linearLayout = (LinearLayout) findViewById(R.id.samples);
		filterRadio = (RadioGroup) findViewById(R.id.filter_radio_group);

		filterRadio.setOnCheckedChangeListener(new OnCheckedChangeListener() {

			@Override
			public void onCheckedChanged(RadioGroup group, int checkedId) {
				if (checkedId != -1) {

					if (checked != null)
						checked.setAlpha(1);
					checked = (RadioButton) findViewById(filterRadio.getCheckedRadioButtonId());
					checked.setAlpha((float) 0.5);

					reloadMarkers(Integer.parseInt(checked.getTag().toString()), true);

				}
			}
		});
		Log.i("creations", "create");
		itemDefaultMarker = getResources().getDrawable(R.drawable.det);
		rasMarker = getResources().getDrawable(R.drawable.marker_green);

		masquedMarker = getResources().getDrawable(R.drawable.masq);

		illisibleMarker = getResources().getDrawable(R.drawable.ill);

		manqMarker = getResources().getDrawable(R.drawable.mnq);

		malMarker = getResources().getDrawable(R.drawable.mal);

		login = MainActivity.login;

		// mapView = new MapView(this);
		mapView = (MapView) findViewById(R.id.mapview_content_frame);
		mapView.setClickable(true);
		mapView.setBuiltInZoomControls(true);

		// mapView.setOnLongClickListener(new OnLongClickListener() {
		//
		// @Override
		// public boolean onLongClick(View v) {
		// MapView mv = (MapView) v;
		// mv.get
		// return false;
		// }
		// });
		FileOpenResult fileOpenResult = mapView.setMapFile(MAP_FILE);
		if (!fileOpenResult.isSuccess()) {
			Toast.makeText(this, fileOpenResult.getErrorMessage(), Toast.LENGTH_LONG).show();
			finish();
		}

		// setContentView(mapView);
		// create the default paint objects for overlay ways

		paintMissionArea();

		if (checked == null)
			reloadMarkers(-1, false);
		else
			reloadMarkers(Integer.parseInt(checked.getTag().toString()), false);

	}

	public void showPopup(View v) {
		PopupMenu popup = new PopupMenu(this, v);
		MenuInflater inflater = popup.getMenuInflater();
		inflater.inflate(R.menu.main_menu, popup.getMenu());
		popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
			@Override
			public boolean onMenuItemClick(MenuItem item) {
				switch (item.getItemId()) {

					case R.id.save_work:
						saveWork();
						return true;
					case R.id.exit:
						logout();
						return true;

				}
				return true;
			}
		});

		popup.show();
	}

	private void paintMissionArea() {

		wayOverlay = new Ways(wayDefaultPaintFill, wayDefaultPaintOutline);

		OverlayWay way1;
		List<GeoPoint> geoList = PointsExtractor.getPoints(GEO_JSON_FILE);

		way1 = new OverlayWay(new GeoPoint[][] { PointsExtractor.getPoints(GEO_JSON_FILE).toArray(
				new GeoPoint[geoList.size()]) });
		// create the WayOverlay and add the ways

		wayOverlay.addWay(way1);

		mapView.getOverlays().add(wayOverlay);
	}

	protected void reloadMarkers(int category, boolean filterReload) {

		if (itemizedOverlay == null) {
			itemizedOverlay = new MyItemizedOverlay(itemDefaultMarker, this);

		}

		if (filterReload)
			itemizedOverlay.clear();

		if (!(alertPoints.size() == 0)) {

			for (AlertPoint point : alertPoints) {

				if ((category == -1) || ((category != -1) && point.getCatid() == category)) {
					addMarker(point);

				}

				// else
				// removeMarker(point);
			}
			Log.i("resume", "resume");

		}

		if (!filterReload)
			mapView.getOverlays().add(itemizedOverlay);

	}

	public void addMarker(AlertPoint newPoint) {

		Drawable marker = itemDefaultMarker;

		switch (newPoint.getCatid()) {

			case 2:
				marker = masquedMarker;
				break;
			case 3:
				marker = manqMarker;
				break;
			case 4:
				marker = rasMarker;
				break;
			case 5:
				marker = illisibleMarker;
				break;
			case 6:
				marker = malMarker;
				break;

		}

		OverlayItem item = new OverlayItem(new GeoPoint((newPoint.getGmlat()), newPoint.getGmlng()), ""
				+ newPoint.getCatid(), newPoint.getStreet(), ItemizedOverlay.boundCenterBottom(marker));

		alertItems.add(item);
		itemizedOverlay.addItem(item);

		// int index = mapView.getOverlays().indexOf(itemizedOverlay);
		//
		// if (index != -1){
		// mapView.getOverlays().remove(index);
		// ((MyItemizedOverlay) (mapView.getOverlays().get(index))).addItem(item);
		//
		// }
		// else
		//

	}

	public void removeMarker(AlertPoint point) {

		int index = alertPoints.indexOf(point);

		OverlayItem item = alertItems.get(index);

		itemizedOverlay.removeItem(item);
		Log.i("remove", "remove");

	}

	public void logout() {
		SharedPreferences sharedpreferences = getSharedPreferences("prefs", Context.MODE_PRIVATE);
		Editor editor = sharedpreferences.edit();
		editor.clear();
		editor.commit();
		moveTaskToBack(true);
		this.finish();

	}

	@Override
	protected void onRestart() {
		Log.i("restart", "restart");
		super.onRestart();
	}

	@Override
	protected void onStart() {
		Log.i("start", "start");
		super.onStart();
	}

	class Ways extends ArrayWayOverlay {

		public Ways(Paint defaultPaintFill, Paint defaultPaintOutline) {
			super(defaultPaintFill, defaultPaintOutline);
			// TODO Auto-generated constructor stub
		}

		@Override
		public boolean onLongPress(GeoPoint geoPoint, MapView mapView) {
			Intent intent = new Intent(mapView.getContext(), NewPointDialogActivity.class);
			Bundle b = new Bundle();

			AlertPoint alertPoint = new AlertPoint();
			alertPoint.setGmlat(geoPoint.getLatitude());
			alertPoint.setGmlng(geoPoint.getLongitude());
			alertPoint.setCreated_by_alias(login);

			b.putSerializable("alertPoint", alertPoint);
			intent.putExtras(b);

			// dialog.setAlertPoint(new AlertPoint(geoPoint));

			startActivity(intent);
			System.out.println(geoPoint.latitudeE6);
			return super.onLongPress(geoPoint, mapView);
		}
	}

	// public void reloadMarkers(List<AlertPoint> alertPoints) {
	//
	// if (itemizedOverlay == null)
	// itemizedOverlay = new MyItemizedOverlay(null, this);
	// for (AlertPoint alert : alertPoints) {
	// OverlayItem item = new OverlayItem(new GeoPoint((alert.getGmlat()), alert.getGmlng()), ""
	// + alert.getCatid(), alert.getStreet());
	//
	// itemizedOverlay.addItem(item);
	// }
	//
	// mapView.getOverlays().add(itemizedOverlay);
	// }

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.main_menu, menu);

		return super.onCreateOptionsMenu(menu);
	}

	@Override
	public void onBackPressed() {

	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {

			case android.R.id.home:
				Log.i("home", "home");

				showPopup(findViewById(android.R.id.home));
				return true;
			case R.id.save_work:
				saveWork();
				return true;
			case R.id.exit:
				logout();
				return true;
			default:
				return super.onOptionsItemSelected(item);
		}
	}

	public void saveWork() {
		ObjectMapper mapper = new ObjectMapper();
		File jsonDir = new File(JSON_DIR);
		if (!jsonDir.isDirectory())
			jsonDir.mkdirs();
		File jsonFile = new File(JSON_DIR
				+ getSharedPreferences("prefs", Context.MODE_PRIVATE).getString("missionCode", "default") + ".json");
		try {
			jsonFile.createNewFile();
			mapper.writeValue(jsonFile, alertPoints);
			// uploadFile(jsonFile);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	// /**
	// * Shows the progress UI and hides the login form.
	// */
	// @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
	// private void showProgress(final boolean show) {
	// // On Honeycomb MR2 we have the ViewPropertyAnimator APIs, which allow
	// // for very easy animations. If available, use these APIs to fade-in
	// // the progress spinner.
	// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
	// int shortAnimTime = getResources().getInteger(android.R.integer.config_shortAnimTime);
	//
	// mLoginStatusView.setVisibility(View.VISIBLE);
	// mLoginStatusView.animate().setDuration(shortAnimTime).alpha(show ? 1 : 0)
	// .setListener(new AnimatorListenerAdapter() {
	// @Override
	// public void onAnimationEnd(Animator animation) {
	// mLoginStatusView.setVisibility(show ? View.VISIBLE : View.GONE);
	// }
	// });
	//
	// mLoginFormView.setVisibility(View.VISIBLE);
	// mLoginFormView.animate().setDuration(shortAnimTime).alpha(show ? 0 : 1)
	// .setListener(new AnimatorListenerAdapter() {
	// @Override
	// public void onAnimationEnd(Animator animation) {
	// mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
	// }
	// });
	// } else {
	// // The ViewPropertyAnimator APIs are not available, so simply show
	// // and hide the relevant UI components.
	// mLoginStatusView.setVisibility(show ? View.VISIBLE : View.GONE);
	// mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
	// }
	// }

	void uploadFile(File alertPointsJson) throws IOException {

		SimpleFTP ftp = new SimpleFTP();

		// Connect to an FTP server on port 21.
		ftp.connect(" ftp.odonym.com", 21, "u75263135-od-flux", "Elgoussa%2014");

		// Set binary mode.
		ftp.bin();

		// Change to a new working directory on the FTP server.

		ftp.cwd("json");

		// Upload some files.
		ftp.stor(alertPointsJson);

		// Quit from the FTP server.
		ftp.disconnect();
	}

}
